#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lista.h"

#ifndef _LISTA_C_
#define _LISTA_C_

struct tac* create_inst_tac(int type, const char* res, const char* arg1, const char* op, const char* arg2) {

   struct tac *t = (struct tac *)malloc(sizeof(struct tac));

   t->type = type;

   t->op = (char*)malloc(sizeof(char) * (1 + strlen(op)));

   strcpy(t->op, op);

   t->res = (char*)malloc(sizeof(char) * (1 + strlen(res)));

   strcpy(t->res, res);

   t->arg1 = (char*)malloc(sizeof(char) * (1 + strlen(arg1)));

   strcpy(t->arg1, arg1);

   t->arg2 = (char*)malloc(sizeof(char) * (1 + strlen(arg2)));

   strcpy(t->arg2, arg2);

   return(t);
}

void print_inst_tac(FILE* out, struct tac i, int ordem) {

	char *rotulo = malloc(sizeof(char) * 4);	
	
	sprintf(rotulo, "%03d", ordem);
		
	fprintf(out, "%s:   ", rotulo);
	
	if(i.type == TACTYPE_PRINT) {
		fprintf(out, "PRINT %s\n", i.res);
	}
	if(i.type == TACTYPE_ATTRIB) {
		if(strcmp(i.op, ":=") == 0)
			fprintf(out, "%s := %s\n", i.res, i.arg1);
		else
			fprintf(out, "%s := %s %s %s\n", i.res, i.arg1, i.op, i.arg2);
	}
}

void print_tac(FILE* out, node_tac* code) {
	
	struct tac* aux_tac;
	int ordem = 0;
	
	while(code != NULL) {
		aux_tac = code->inst;
		print_inst_tac(out, *aux_tac, ordem);
		ordem++;
		code = code->next;
	}
}

void append_inst_tac(node_tac** code, struct tac* inst) {

	node_tac* new_node = (node_tac*)malloc(sizeof(node_tac));
	new_node->inst = inst;
	new_node->next = NULL;
	
	if (*code == NULL) { /** lista vazia */
		new_node->prev = NULL;
		*code = new_node;
	} 
	else {
	
		node_tac* node = *code;
	
		while(node->next != NULL) {
			node = node->next;
		}
	
		node->next = new_node;
		new_node->prev = node;
	}
}

void cat_tac(node_tac** code_a, node_tac** code_b) {
	if (*code_b != NULL) { 
		
		if (*code_a == NULL) { 
			*code_a = *code_b;
		} 
		else { 
			
			node_tac* aux_node = *code_a;
			while(aux_node->next != NULL) {
				aux_node = aux_node->next;
			};
			
			aux_node->next = *code_b;
		};
	};
}

#endif
